package no.sachmuld.methodcombination.demo;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.servlet.*;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

/**
 *
 */
public class DemoInitializer implements ServletContainerInitializer {

    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {

        DataSource dataSource = createDateSource();

        migrateDatabase(dataSource);

        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);

        TransactionBehaviour transactionBehaviour = new TransactionBehaviour(transactionManager);
        LoggingBehaviour loggingBehaviour = new LoggingBehaviour();

        EmployeeRepository employeeRepository = new EmployeeRepository(dataSource);
        employeeRepository.with(loggingBehaviour, transactionBehaviour);

        addMethodCombinationFilter(ctx, "demo", "/demo/*", new ForwardFilterBehaviour("index.html"));
        addMethodCombinationFilter(ctx, "employees", "/employees/*", new RestFilterBehaviour<>(employeeRepository, Employee.class));

    }

    private DataSource createDateSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(org.postgresql.Driver.class.getName());
        dataSource.setUsername("demo");
        dataSource.setPassword("demo");
        dataSource.setUrl("jdbc:postgresql://localhost/demo");
        dataSource.setInitialSize(1);
        return dataSource;
    }

    private void migrateDatabase(DataSource dataSource) {

        List<DatabaseMigrater.Migration> migrations = Arrays.asList(
                new DatabaseMigrater.Migration(1, "create DATABASE_MIGRATIONS table", DatabaseMigrater.ScriptType.DDL, "sql/001.sql"),
                new DatabaseMigrater.Migration(2, "create EMPLOYEE table", DatabaseMigrater.ScriptType.DDL, "sql/002.sql")
        );

        new DatabaseMigrater().execute(dataSource, migrations);
    }

    private void addMethodCombinationFilter(ServletContext ctx, String name, String mapping, FilterBehaviour... behaviours) {
        MethodCombinationFilter filter = new MethodCombinationFilter();
        filter.with(new LoggingFilterBehaviour(), new ExceptionMappingFilterBehaviour());
        filter.with(behaviours);
        FilterRegistration filterRegistration = ctx.addFilter(name, filter);
        filterRegistration.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, new String[] {mapping});
    }


}
